import threading
from gglib.io import IOSelector, IO_READ, IO_WRITE
from select import select as ss


class SelectIO(IOSelector):
    def __init__(self):
        self.read_list = []
        self.write_list = []
        self._lock = threading.RLock()

    def register_event(self, fd, ev):
        with self._lock:
            if ev & IO_READ and fd not in self.read_list:
                self.read_list.append(fd)
            if ev & IO_WRITE and fd not in self.write_list:
                self.write_list.append(fd)

    def unregister_event(self, fd):
        with self._lock:
            if fd in self.read_list:
                self.read_list.remove(fd)
            if fd in self.write_list:
                self.write_list.remove(fd)

    def wait_events(self, timeout=None):
        read_fds, write_fds, _ = ss(self.read_list, self.write_list, [], timeout)
        for r in read_fds:
            yield r, IO_READ
        for r in write_fds:
            yield r, IO_WRITE
